package com.ysd.lis.service.samsto.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import com.ysd.common.Result;
import com.ysd.lis.dto.samsto.SamstoStorageFridgeDto;
import com.ysd.lis.entity.SysUser;
import com.ysd.lis.entity.samsto.*;
import com.ysd.lis.mapper.samsto.SamstoStorageFridgeMapper;
import com.ysd.lis.request.samsto.SamstoStorageFridgeParam;
import com.ysd.lis.service.samsto.*;
import com.ysd.util.RedisUserManager;
import com.ysd.util.ToolsUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

/**
 * (SamstoStorageFridge)表服务实现类
 *
 * @author leiming
 * @since 2024-10-28 15:23:06
 */
@Service("samstoStorageFridgeService")
public class SamstoStorageFridgeServiceImpl extends ServiceImpl<SamstoStorageFridgeMapper, SamstoStorageFridge> implements SamstoStorageFridgeService {

    @Autowired
    private SamstoFridgeLayerService samstoFridgeLayerService;

    @Autowired
    private SamstoSpecboxOrderReqService samstoSpecboxOrderReqService;

    @Autowired
    private SamstoFridgeService samstoFridgeService;
    @Autowired
    private SamstoSpecboxService samstoSpecboxService;
    @Autowired
    private SamstoStorageFridgeMapper storageFridgeMapper;


    private MPJLambdaWrapper<SamstoStorageFridge> initWrapper() {
        MPJLambdaWrapper<SamstoStorageFridge> lambdaQueryWrapper = new MPJLambdaWrapper<>();
        //ID
        lambdaQueryWrapper.selectAs(SamstoStorageFridge::getId, SamstoStorageFridgeDto::getId);
        //仓库ID
        lambdaQueryWrapper.selectAs(SamstoStorageFridge::getStorageId, SamstoStorageFridgeDto::getStorageId);
        //${column.comment}
        lambdaQueryWrapper.selectAs(SamstoStorageFridge::getFridgeId, SamstoStorageFridgeDto::getFridgeId);
        //关联关系
        lambdaQueryWrapper.selectAs(SamstoStorageFridge::getLinkType, SamstoStorageFridgeDto::getLinkType);
        return lambdaQueryWrapper;
    }

    @Override
    public Result findPageList(SamstoStorageFridgeParam pageParam) {
        Page<SamstoStorageFridge> pageList = null;
        LambdaQueryWrapper<SamstoStorageFridge> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        Page<SamstoStorageFridge> page = new Page<SamstoStorageFridge>();
        page.setCurrent(pageParam.getPageIndex());
        page.setSize(pageParam.getPageSize());
        pageList = this.baseMapper.selectPage(page, lambdaQueryWrapper);
        return Result.succ(1, "获取信息成功", pageList);
    }

    @Override
    public Result getAllList(SamstoStorageFridgeParam pageParam) {
        List<SamstoStorageFridgeDto> allList = null;
        MPJLambdaWrapper<SamstoStorageFridge> infoWrapper = initWrapper();
        infoWrapper.selectAs(SamstoFridge::getBoxCode, SamstoStorageFridgeDto::getItemCode);
        infoWrapper.selectAs(SamstoFridgeModel::getModelName, SamstoStorageFridgeDto::getItemName);
        infoWrapper.leftJoin(SamstoFridge.class, SamstoFridge::getId, SamstoStorageFridge::getFridgeId);
        infoWrapper.leftJoin(SamstoFridgeModel.class, SamstoFridgeModel::getId, SamstoFridge::getFrimodId);
        infoWrapper.eq(SamstoStorageFridge::getStorageId, pageParam.getStorageId());
        allList = this.baseMapper.selectJoinList(SamstoStorageFridgeDto.class, infoWrapper);
        return Result.succ(1, "获取信息成功", allList);
    }

    @Override
    public Result getStorageFridgeList(SamstoStorageFridgeParam pageParam) {
        List<SamstoStorageFridgeDto> allList = null;
        MPJLambdaWrapper<SamstoStorageFridge> infoWrapper = initWrapper();
        infoWrapper.selectAs(SamstoFridge::getBoxCode, SamstoStorageFridgeDto::getItemCode);
        infoWrapper.selectAs(SamstoFridge::getId, SamstoStorageFridgeDto::getFridgeId);
        infoWrapper.selectAs(SamstoFridge::getFrigTemp, SamstoStorageFridgeDto::getFrigTemp);
        infoWrapper.selectAs(SamstoFridge::getFreezeTemp, SamstoStorageFridgeDto::getFreezeTemp);
        infoWrapper.selectAs(SamstoFridgeModel::getModelName, SamstoStorageFridgeDto::getItemName);
        infoWrapper.leftJoin(SamstoFridge.class, SamstoFridge::getId, SamstoStorageFridge::getFridgeId);
        infoWrapper.leftJoin(SamstoFridgeModel.class, SamstoFridgeModel::getId, SamstoFridge::getFrimodId);
        infoWrapper.eq(SamstoStorageFridge::getStorageId, pageParam.getStorageId());
        allList = this.baseMapper.selectJoinList(SamstoStorageFridgeDto.class, infoWrapper);

        //根据冰箱去查找试剂盒,根据层数分组
        if (CollectionUtils.isNotEmpty(allList)) {
            //查询层架
            List<String> fridgeIds = allList.stream().map(SamstoStorageFridgeDto::getFridgeId).filter(StringUtils::isNotBlank).collect(Collectors.toList());
            List<SamstoFridgeLayer> fridgeLayerList = samstoFridgeLayerService.list(new LambdaQueryWrapper<SamstoFridgeLayer>().in(SamstoFridgeLayer::getFridgeId, fridgeIds).eq(SamstoFridgeLayer::getDelFlag, 0).orderByAsc(SamstoFridgeLayer::getLayerSeq));
            Map<String, List<SamstoFridgeLayer>> fridgeLayerMap = fridgeLayerList.stream().collect(Collectors.groupingBy(SamstoFridgeLayer::getFridgeId));
            //取出试剂盒
            LambdaQueryWrapper<SamstoSpecbox> boxWrapper = new LambdaQueryWrapper<>();
            boxWrapper.in(SamstoSpecbox::getFridgeId, fridgeIds);
            boxWrapper.eq(SamstoSpecbox::getDelFlag, 0);
            List<SamstoSpecbox> specboxList = samstoSpecboxService.list(boxWrapper);
            Map<String, List<SamstoSpecbox>> specboxMap = specboxList.stream().collect(Collectors.groupingBy(SamstoSpecbox::getFridgeId));

            //获取孔位销毁时间逾期
            // 获取昨天的开始时间和结束时间
            LocalDateTime startOfYesterday = LocalDate.now().minusDays(1).atStartOfDay();
            LocalDateTime endOfYesterday = startOfYesterday.plusDays(1).minusNanos(1);
            LambdaQueryWrapper<SamstoSpecboxOrderReq> orderReqWrapper = new LambdaQueryWrapper<>();
            orderReqWrapper.in(SamstoSpecboxOrderReq::getFridgeId, fridgeIds);
            // 设置查询条件，destroyTime字段值在昨天的范围内
            orderReqWrapper.between(SamstoSpecboxOrderReq::getDestroyTime, startOfYesterday, endOfYesterday);
            orderReqWrapper.ne(SamstoSpecboxOrderReq::getStatus, 10);
            orderReqWrapper.eq(SamstoSpecboxOrderReq::getDelFlag, 0);
            List<SamstoSpecboxOrderReq> orderReqList = samstoSpecboxOrderReqService.list(orderReqWrapper);
            Map<String, List<SamstoSpecboxOrderReq>> orderReqMap = orderReqList.stream().collect(Collectors.groupingBy(SamstoSpecboxOrderReq::getFridgeId));

            //查询冰箱基础信息
            List<SamstoStorageFridgeDto> fridgeData = storageFridgeMapper.getFridgeData();
            Map<String, List<SamstoStorageFridgeDto>> fridgeMap = fridgeData.stream().collect(Collectors.groupingBy(SamstoStorageFridgeDto::getFridgeId));
            //查询试剂盒
            for (SamstoStorageFridgeDto samstoStorageFridgeDto : allList) {
                //统计快逾期的多少标本盒和空位
                List<SamstoSpecboxOrderReq> orderReqList1 = orderReqMap.get(samstoStorageFridgeDto.getFridgeId());
                if (CollectionUtils.isNotEmpty(orderReqList1)) {
                    samstoStorageFridgeDto.setTimeoutOrderNum(orderReqList1.size());
                    //统计快过期的盒
                    Set<String> specboxIdSet = orderReqList1.stream().map(SamstoSpecboxOrderReq::getSpecboxId).collect(Collectors.toSet());
                    samstoStorageFridgeDto.setTimeoutBoxNum(specboxIdSet.size());
                }
                List<SamstoStorageFridgeDto> samstoStorageFridgeDtos = fridgeMap.get(samstoStorageFridgeDto.getFridgeId());
                if (CollectionUtils.isNotEmpty(samstoStorageFridgeDtos)) {
                    Integer ssoNum = samstoStorageFridgeDtos.get(0).getSsoNum();
                    Integer ssoNotEemptyNum = samstoStorageFridgeDtos.get(0).getSsoNotEemptyNum();
                    if (Objects.isNull(ssoNum) || Objects.isNull(ssoNotEemptyNum)) {
                        samstoStorageFridgeDto.setUseNum(0 + "%");
                        samstoStorageFridgeDto.setNotUseNum(100 + "%");
                    } else {
                        int useNum = (int) ((ssoNotEemptyNum * 1.0 / ssoNum) * 100);
                        int notUseNum = 100 - useNum;
                        samstoStorageFridgeDto.setUseNum(useNum + "%");
                        samstoStorageFridgeDto.setNotUseNum(notUseNum + "%");
                    }
                }

                List<SamstoFridgeLayer> fridgeLayerList1 = fridgeLayerMap.get(samstoStorageFridgeDto.getFridgeId());
                if (CollectionUtils.isNotEmpty(fridgeLayerList1)) {
                    for (SamstoFridgeLayer samstoFridgeLayer : fridgeLayerList1) {
                        List<SamstoSpecbox> specboxList1 = specboxMap.get(samstoFridgeLayer.getFridgeId());
                        if (CollectionUtils.isNotEmpty(specboxList1)) {
                            Map<String, List<SamstoSpecbox>> listMap = specboxList1.stream().collect(Collectors.groupingBy(SamstoSpecbox::getLayerId));
                            List<SamstoSpecbox> samstoSpecboxVos = listMap.get(samstoFridgeLayer.getId());
                            samstoFridgeLayer.setSpecboxList(samstoSpecboxVos);
                        }
                    }
                }
                samstoStorageFridgeDto.setFridgeLayerList(fridgeLayerList1);
            }
        }
        List<SamstoStorageFridgeDto> collect = allList.stream().filter(samstoStorageFridgeDto -> CollectionUtils.isNotEmpty(samstoStorageFridgeDto.getFridgeLayerList())).collect(Collectors.toList());
        return Result.succ(1, "获取信息成功", allList);
    }

    @Override

    public Result getStorageFridgeById(SamstoStorageFridge samstoStorageFridge) {

        SamstoStorageFridgeDto samstoStorageFridgeDto = new SamstoStorageFridgeDto();
        //查询层架
        List<SamstoFridgeLayer> fridgeLayerList = samstoFridgeLayerService.list(new LambdaQueryWrapper<SamstoFridgeLayer>().eq(SamstoFridgeLayer::getFridgeId, samstoStorageFridge.getId()).eq(SamstoFridgeLayer::getDelFlag, 0).orderByAsc(SamstoFridgeLayer::getLayerSeq));
        //取出试剂盒
        LambdaQueryWrapper<SamstoSpecbox> boxWrapper = new LambdaQueryWrapper<>();
        boxWrapper.in(SamstoSpecbox::getFridgeId, samstoStorageFridge.getId());
        boxWrapper.eq(SamstoSpecbox::getDelFlag, 0);
        List<SamstoSpecbox> specboxList = samstoSpecboxService.list(boxWrapper);

        //查询试剂盒
        for (SamstoFridgeLayer samstoFridgeLayer : fridgeLayerList) {
            if (CollectionUtils.isNotEmpty(specboxList)) {
                Map<String, List<SamstoSpecbox>> listMap = specboxList.stream().collect(Collectors.groupingBy(SamstoSpecbox::getLayerId));
                List<SamstoSpecbox> samstoSpecboxVos = listMap.get(samstoFridgeLayer.getId());
                samstoFridgeLayer.setSpecboxList(samstoSpecboxVos);
            }
        }
        samstoStorageFridgeDto.setFridgeLayerList(fridgeLayerList);

        return Result.succ(1, "获取信息成功", samstoStorageFridgeDto);
    }

    @Override
    public Result findListByGId(SamstoStorageFridgeParam pageParam) {
        Page<SamstoStorageFridge> pageList = null;
        LambdaQueryWrapper<SamstoStorageFridge> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        Page<SamstoStorageFridge> page = new Page<SamstoStorageFridge>();
        page.setCurrent(pageParam.getPageIndex());
        page.setSize(pageParam.getPageSize());
        pageList = this.baseMapper.selectPage(page, lambdaQueryWrapper);
        return Result.succ(1, "获取信息成功", pageList);
    }

    @Override
    public Result getInfoById(String id) {
        SamstoStorageFridge SamstoStorageFridge = this.baseMapper.selectById(id);
        return Result.succ(1, "获取信息成功", SamstoStorageFridge);
    }

    @Override
    public Result add(SamstoStorageFridgeParam param) {
        SamstoStorageFridge info = new SamstoStorageFridge();
        BeanUtil.copyProperties(param, info);
        this.baseMapper.insert(info);
        return Result.succ(1, "添加信息成功", null);
    }

    @Override
    public Result edit(SamstoStorageFridgeParam param) {
        Map returnMap = new HashMap();
        SamstoStorageFridge info = new SamstoStorageFridge();
        BeanUtil.copyProperties(param, info);
        this.baseMapper.updateById(info);
        returnMap.put("id", param.getId());
        return Result.succ(1, "修改信息成功", returnMap);
    }

    @Override
    public Result delete(List<String> ids) {
        Result result;
        try {
            boolean b = this.removeByIds(ids);
            if (b) {
                result = Result.succ(1, "删除成功", null);
            } else {
                result = Result.fail(400, "删除失败", "");
            }
        } catch (Exception e) {
            e.printStackTrace();
            result = Result.fail(400, "删除失败", "");
        }
        return result;
    }

    @Transactional
    @Override
    public Result saveOrUpdateList(SamstoStorageFridgeParam param) {
        Result result;
        try {
            SysUser sysUser = RedisUserManager.getUser();
            if (ToolsUtils.isEmpty(sysUser)) {
                return Result.fail(304, "请重新登陆", "");
            }
            for (SamstoStorageFridge info : param.getInfoList()) {
                if (StringUtils.isNotBlank(info.getId())) {
                    this.baseMapper.updateById(info);
                } else {
                    this.baseMapper.insert(info);
                }
            }
            Boolean b = this.saveOrUpdateBatch(param.getInfoList());
            if (b) {
                result = Result.succ(1, "保存成功", null);
            } else {
                result = Result.fail(400, "保存失败", "");
            }
        } catch (Exception e) {
            e.printStackTrace();
            result = Result.fail(400, "保存失败", "");
        }
        return result;
    }
}

